#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

#import <objc/ObjCModule.h>
#import <objc/objc-class.h>
#import <objc/objc_sel.h>
#import <objc/objc_class.h>
#include <assert.h>



void* libc=0;
void* libmach=0;
void* libobjc=0;
void* libringo=0;
void (*_dyld_link_objc)(int dyldversion,int nmess,SEL* sels,int nmods,OBJCModule* mods,int nrefs,Class* refs);
id (*_objc_getClass)(const char *name);

extern void qerror(char*,...);




static inline void* loadlib(char* l)
{
	//printf("loading %s\n",l);
	void* v=dlopen(l,RTLD_NOW);
	if(v==0) qerror("library not found: %s",l);
	return v;
}
void loadLibSystem()
{
	libc=loadlib("/lib/libc.so.6");
	libringo=loadlib("libringo.so");
	libobjc=loadlib("libobjc.so");
	_dyld_link_objc = dlsym(libobjc,"_dyld_link_objc");
	assert(_dyld_link_objc);
	_objc_getClass = dlsym(libobjc,"objc_getClass");


	//libdyld apis is in libringo
	void (*dyld_apis_init_libsystem)(void*);
	dyld_apis_init_libsystem=dlsym(libringo,"dyld_apis_init_libsystem");
	dyld_apis_init_libsystem((void*)loadLibSystem);

	

}

void* dyld_unimp()
{
	printf("unimp\n");
	exit(0);
	return 0;
}

void* libsystem_dlsym(char* sym)
{

	void* s;
	s=dlsym(libringo,sym);
	if(s==0) s=dlsym(libc,sym+1);//macosx uses _
	int pos;
	if(s==0) 
	{
		pos = strcspn(sym,"$");
		if(pos!=strlen(sym))
		{
		char dest[pos];
		memcpy(dest,sym+1,pos-1);
		dest[pos-1]=0;
		return dlsym(libc,dest);
		}
	}
	if(s==0) s=dlsym(libringo,sym+1);
	if(s==0) s=dlsym(libobjc,sym+1);
	if(s==0) s=dlsym(libc,sym);
	//TIGER abi
	//if(s==0 && strcmp(sym,"_NSAddressOfSymbol")==0) s=dyld_unimp();
	//if(s==0 && strcmp(sym,"_NSIsSymbolNameDefined")==0) s=dyld_unimp();
	return s;
}
